package com.xeem.core.net
{
	import flash.events.EventDispatcher;
	
	/**
	 * socket基础封装，发送接受指定字符串到服务器
	 * @version 1.0
	 * @fp version 9
	 */
	
	public class Socket extends EventDispatcher
		{
			private var socket:Socket;//socket
			private var _host:String;//主机ip
			private var _port:uint;//端口
			private var _isConn:Boolean;//连接状态
			private var _isAllListener:Boolean = false;//事件注册状态
			
			private var timer:Timer;
			private var _delay:uint;
			
			/**
			 * sokcet
			 * @param	host 主机ip
			 * @param	port 端口 0~60035
			 * @param	delay 反复连接 默认5秒钟 0为一次性连接
			 */
			public function Socket(host:String = "localhost", port:uint = 7777, delay:uint = 5)
			{
				this._host = host;
				this._port = port;
				this._delay = delay;
			}
			
			/* all events */
			/**
			 * 处理事件
			 * @param	event
			 */
			private function handler(event:Event):void 
			{
				trace(event.type);
				switch(event.type)
				{  
					case Event.CLOSE:
						this.dispatchEvent(new SocketsEvent(SocketsEvent.CLOSE));
						
						this.startDelay();
						break; 
					
					case Event.CONNECT:					
						this.dispatchEvent(new SocketsEvent(SocketsEvent.CONNECT));
						
						if (timer != null)
						{
							timer.stop();
						}
						break;
					
					case IOErrorEvent.IO_ERROR:
						this.dispatchEvent(new SocketsEvent(SocketsEvent.IO_ERROR));
						
						this.startDelay();
						break;
					
					case SecurityErrorEvent.SECURITY_ERROR:
						this.dispatchEvent(new SocketsEvent(SocketsEvent.SECURITY_ERROR));
						break;
					
					case ProgressEvent.SOCKET_DATA:
						this.received();
						break;
				}
			}
			
			/**
			 * 
			 * @param	e
			 */
			private function onTimer(e:TimerEvent):void 
			{
				this.connect();
			}
			
			/* all private */
			/**
			 * 接受来自服务器的字符串
			 * @return  void
			 */
			private function received():void
			{
				var str:String = socket.readUTFBytes(socket.bytesAvailable);
				this.dispatchEvent(new SocketsEvent(SocketsEvent.RECEIVED, str));
				trace(str);
			}
			
			/**
			 * 反复连接
			 * @return  void
			 */
			private function startDelay():void
			{
				if (this._delay > 0)
				{
					if (timer == null)
					{
						timer = new Timer(this._delay * 1000);
						if (!timer.hasEventListener(TimerEvent.TIMER))
						{
							timer.addEventListener(TimerEvent.TIMER, onTimer);
						}
					}
					
					if (!timer.running)
					{
						timer.start();
					}
				}
			}
			
			/* all public */
			/**
			 * 添加所有事件
			 * @return  void
			 */
			public function addAllEventListener():void
			{
				if (!this._isAllListener && socket != null)
				{
					socket.addEventListener(Event.CONNECT, handler);
					socket.addEventListener(Event.CLOSE, handler);
					socket.addEventListener(IOErrorEvent.IO_ERROR, handler);
					socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handler);
					socket.addEventListener(ProgressEvent.SOCKET_DATA, handler);
					this._isAllListener = true;
				}			
			}
			
			/**
			 * 删除所有事件
			 * @return  void
			 */
			public function removeAllEventListener():void
			{
				if (this._isAllListener && socket != null)
				{
					socket.removeEventListener(Event.CONNECT, handler);
					socket.removeEventListener(Event.CLOSE, handler);
					socket.removeEventListener(IOErrorEvent.IO_ERROR, handler);
					socket.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, handler);
					socket.removeEventListener(ProgressEvent.SOCKET_DATA, handler);
					this._isAllListener = false;
				}
				
				timer.stop();
				timer.removeEventListener(TimerEvent.TIMER, onTimer);
			}
			
			/**
			 * 发送字符串到服务器
			 * @param	str
			 * @return  void
			 */
			public function send(str:String):void
			{
				if (this.isConn)
				{
					try
					{
						socket.writeUTFBytes(str);
						socket.flush();
					}catch (e:Error)
					{
						throw new Error("发送失败");
					}
				}
				else
				{
					trace("网络断开，发送失败");
				}
			}
			
			/**
			 * 销毁连接
			 * @return  void
			 */
			public function destroy():void
			{
				removeAllEventListener();
				socket = null;
			}
			
			/**
			 * 连接到服务器
			 * @return  void
			 */
			public function connect():void
			{
				if (this.socket == null)
				{
					this.socket = new Socket();
					this.addAllEventListener();
					socket.connect(_host, _port);
				}
				else
				{
					if (!this.socket.connected)
					{
						this.addAllEventListener();
						socket.connect(_host, _port);
					}
				}
			}
			
			/**
			 * 关闭连接
			 * @return  void
			 */
			public function close():void
			{
				socket.close();
			}
			
			/**
			 * 载入跨域文件
			 * @param	str
			 * @return  void
			 */
			public function loadPolicyFile(str:String = "cross-domain.xml"):void
			{
				Security.loadPolicyFile(str);
			}
			
			/* all getter setter */
			/**
			 * 端口
			 * @return  int
			 */
			public function get port():int 
			{ 
				return _port; 
			}
			
			/**
			 * 主机ip
			 * @return  String
			 */
			public function get host():String 
			{ 
				return _host; 
			}
			
			/**
			 * 重复连接时间
			 * @return  uint
			 */
			public function get delay():uint 
			{ 
				return _delay; 
			}
			
			/**
			 * 是否连接
			 * @return  Boolean
			 */
			public function get isConn():Boolean 
			{ 
				if (socket != null)
				{
					this._isConn = socket.connected;
				}
				else
				{
					this._isConn = false;
				}
				return _isConn; 
			}
			
			/**
			 * 是否所有监听
			 * @return  Boolean
			 */
			public function get isAllListener():Boolean 
			{ 
				return _isAllListener; 
			}
		}
	}
}